package fina2.dcs.system;

import java.io.File;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.jboss.annotation.ejb.LocalBinding;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;

@Stateful
@Name("propSession")
@Scope(ScopeType.SESSION)
@LocalBinding(jndiBinding = "SysPropertySession/local")
@SuppressWarnings("unchecked")
@AutoCreate
public class SysPropertySession implements SysPropertyLocal, Serializable {

	@PersistenceContext(type=PersistenceContextType.EXTENDED)
	private EntityManager em;

	private List<SysProperty> allProperties = new ArrayList<SysProperty>();

	private SysProperty selectedProperty = new SysProperty();

	private String confirmPassword = null;

	private boolean succes = false;

	@Logger
	private Log log;

	public void addProperty(SysProperty sp) {
		log.info("Adding Properties");
		em.persist(sp);
	}

	public void init() {
		log.info("Initializing properties");
		try {
			allProperties = em.createQuery("SELECT s FROM " + SysProperty.class.getName() + " s WHERE RTRIM(s.propKey) IN('fina2.xml.folder.location','fina2.mfb.xls.name.pattern','fina2.sheet.protection.password','fina2.converted.xmls','fina2.xls.max.size','fina2.zip.max.size') ").getResultList();
			allProperties.add(new SysProperty("fina2.mfb.uploaded.file.unique", "no"));

			log.info("Getting all security settings");
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	@Remove
	@Destroy
	public void remove() {

	}

	public void removeProperty(String propKey) {
		log.info("Searching property " + propKey);
		SysProperty sp = findProperty(propKey);
		if (sp != null) {
			log.info("Property found");
			em.remove(sp);
		} else {
			log.info("Could not find property " + propKey);
		}

	}

	public void updateProperty(SysProperty sp) {
		log.info("Updating property ");
		em.merge(sp);

	}

	public void updateProperty() {
		log.info("Updating Property....");
		try {
			if (!selectedProperty.getPropKey().trim().equals("fina2.sheet.protection.password")) {
				em.merge(selectedProperty);
				log.info("Property Updated");
				succes = true;
			} else {
				File f = new File("tmp.xls");
				f.createNewFile();
				HSSFWorkbook workbook = new HSSFWorkbook();
				workbook.createSheet();

				FileOutputStream fileOut = new FileOutputStream(f);
				workbook.write(fileOut);

				HSSFSheet s = workbook.getSheet("Sheet0");
				s.protectSheet(selectedProperty.getValue());

				selectedProperty.setValue(new Short(s.getPassword()).toString());
				em.merge(selectedProperty);
				log.info("Property Updated");
				succes = true;
				f.delete();
			}
		} catch (Exception ex) {
			succes = false;
			log.error(ex.getMessage(), ex);
		} finally {
			selectedProperty = new SysProperty();
		}
	}

	public SysProperty findProperty(String propKey) {
		// log.info("Searching property " + propKey);
		SysProperty sp = em.find(SysProperty.class, propKey);
		/*
		 * if (sp == null) { log.info("Could not find property"); } else {
		 * log.info("Property found"); }
		 */
		return sp;
	}

	public String findPropValue(String propKey) {
		String val = null;
		try {
			Query q = em.createQuery("SELECT v.value FROM " + SysProperty.class.getName() + " v WHERE RTRIM(v.propKey)=:propKey");
			q.setParameter("propKey", propKey);
			Object o = q.getSingleResult();
			if (o != null)
				val = o.toString();
		} catch (NoResultException ne) {
			val = "";
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return (val != null) ? val.trim() : null;
	}

	public List<SysProperty> findProperties(List<String> propKeys) {
		log.info("Loading Properties For File Upload Validation");
		List<SysProperty> props = new ArrayList<SysProperty>();
		try {
			Query q = em.createQuery("SELECT p FROM " + SysProperty.class.getName() + " p WHERE p.propKey IN (:propKeys)");
			q.setParameter("propKeys", propKeys);
			props = q.getResultList();
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return props;
	}

	public List<SysProperty> getAllProperties() {
		return allProperties;
	}

	public void setAllProperties(List<SysProperty> allProperties) {
		this.allProperties = allProperties;
	}

	public SysProperty getSelectedProperty() {
		return selectedProperty;
	}

	public void setSelectedProperty(SysProperty selectedProperty) {
		succes = false;
		this.selectedProperty = selectedProperty;
	}

	public boolean isSucces() {
		return succes;
	}

	public void setSucces(boolean succes) {
		this.succes = succes;
	}

	public String getConfirmPassword() {
		return confirmPassword;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	public Map<String, String> loadProperties(String... keys) {
		Map<String, String> props = null;
		try {
			log.info("Loading Properties...");
			ArrayList<String> keyList = new ArrayList<String>();
			for (int i = 0; i < keys.length; i++)
				keyList.add(keys[i]);

			Query q = em.createQuery("SELECT s FROM " + SysProperty.class.getName() + " s WHERE s.propKey IN(:keys)");
			q.setParameter("keys", keyList);
			List<SysProperty> params = q.getResultList();
			props = new HashMap<String, String>();
			for (int i = 0; i < params.size(); i++) {
				Object val = params.get(i).getValue();
				props.put(params.get(i).getPropKey(), (val != null) ? val.toString() : null);
			}
			log.info("Properties Loaded...");
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return props;
	}
	public Map<String, String> loadAllProperties() {
		Map<String, String> props = null;
		try {
			log.info("Loading All Properties...");
			
			
			List<SysProperty> params = em.createQuery("SELECT s FROM " + SysProperty.class.getName() + " s ").getResultList();
			props = new HashMap<String, String>();
			for (int i = 0; i < params.size(); i++) {
				Object val = params.get(i).getValue();
				props.put(params.get(i).getPropKey(), (val != null) ? val.toString() : null);
			}
			log.info("Properties Loaded...");
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return props;
	}
}
